#include <gtest/gtest.h>
#include <market_data/market_data_manager.h>
#include <market_data/market_data_source.h>
#include <market_data/market_data_storage.h>
#include <market_data/market_data_monitor.h>
#include <memory>
#include <chrono>
#include <thread>
#include <filesystem>

using namespace hft;
using namespace std::chrono;

// 模拟市场数据源
class MockMarketDataSource : public MarketDataSource {
public:
    MockMarketDataSource() : connected_(false), subscribed_(false) {}
    
    bool connect() override {
        connected_ = true;
        if (connectCallback_) {
            connectCallback_(true);
        }
        return true;
    }
    
    void disconnect() override {
        connected_ = false;
        if (connectCallback_) {
            connectCallback_(false);
        }
    }
    
    bool isConnected() const override {
        return connected_;
    }
    
    bool subscribe(const std::vector<std::string>& symbols) override {
        if (!connected_) return false;
        
        subscribed_ = true;
        subscribedSymbols_ = symbols;
        return true;
    }
    
    bool unsubscribe(const std::vector<std::string>& symbols) override {
        if (!connected_) return false;
        
        // 从已订阅列表中移除
        for (const auto& symbol : symbols) {
            auto it = std::find(subscribedSymbols_.begin(), subscribedSymbols_.end(), symbol);
            if (it != subscribedSymbols_.end()) {
                subscribedSymbols_.erase(it);
            }
        }
        
        subscribed_ = !subscribedSymbols_.empty();
        return true;
    }
    
    // 模拟发送市场数据
    void simulateMarketData(const MarketData& data) {
        if (!connected_ || !subscribed_) return;
        
        // 检查是否订阅了该合约
        auto it = std::find(subscribedSymbols_.begin(), subscribedSymbols_.end(), data.symbol);
        if (it == subscribedSymbols_.end()) return;
        
        // 调用回调函数
        if (dataCallback_) {
            dataCallback_(data);
        }
    }
    
    // 模拟发送错误
    void simulateError(const std::string& errorMsg) {
        if (errorCallback_) {
            errorCallback_(errorMsg);
        }
    }
    
private:
    bool connected_;
    bool subscribed_;
    std::vector<std::string> subscribedSymbols_;
};

class MarketDataManagerTest : public ::testing::Test {
protected:
    void SetUp() override {
        // 创建测试目录
        testDir = "test_data/market_data_manager_test";
        std::filesystem::create_directories(testDir);
        
        // 创建模拟数据源
        mockSource = std::make_shared<MockMarketDataSource>();
        
        // 创建市场数据管理器
        manager = std::make_unique<MarketDataManager>(mockSource);
        
        // 设置存储路径
        manager->setStoragePath(testDir);
        
        // 创建测试数据
        testData.symbol = "IF2309";
        testData.exchange = "CFFEX";
        testData.lastPrice = 3500.0;
        testData.volume = 10000;
        testData.turnover = 35000000.0;
        testData.openInterest = 5000;
        testData.bidPrice1 = 3499.8;
        testData.bidVolume1 = 10;
        testData.askPrice1 = 3500.2;
        testData.askVolume1 = 15;
        testData.timestamp = system_clock::now();
    }

    void TearDown() override {
        // 清理测试目录
        std::filesystem::remove_all(testDir);
        
        // 重置对象
        manager.reset();
        mockSource.reset();
    }

    std::string testDir;
    std::shared_ptr<MockMarketDataSource> mockSource;
    std::unique_ptr<MarketDataManager> manager;
    MarketData testData;
};

TEST_F(MarketDataManagerTest, Initialization) {
    // 验证初始状态
    EXPECT_FALSE(manager->isConnected());
    EXPECT_FALSE(manager->isRunning());
}

TEST_F(MarketDataManagerTest, Connect) {
    // 连接市场数据源
    EXPECT_TRUE(manager->connect());
    EXPECT_TRUE(manager->isConnected());
    
    // 断开连接
    manager->disconnect();
    EXPECT_FALSE(manager->isConnected());
}

TEST_F(MarketDataManagerTest, Subscribe) {
    // 先连接
    EXPECT_TRUE(manager->connect());
    
    // 订阅合约
    std::vector<std::string> symbols = {"IF2309", "IC2309", "IH2309"};
    EXPECT_TRUE(manager->subscribe(symbols));
    
    // 取消订阅
    EXPECT_TRUE(manager->unsubscribe({"IF2309"}));
}

TEST_F(MarketDataManagerTest, ReceiveMarketData) {
    bool dataReceived = false;
    std::string receivedSymbol;
    double receivedPrice = 0.0;
    
    // 设置数据回调
    manager->setMarketDataCallback([&](const MarketData& data) {
        dataReceived = true;
        receivedSymbol = data.symbol;
        receivedPrice = data.lastPrice;
    });
    
    // 连接并订阅
    EXPECT_TRUE(manager->connect());
    EXPECT_TRUE(manager->subscribe({testData.symbol}));
    
    // 启动管理器
    EXPECT_TRUE(manager->start());
    EXPECT_TRUE(manager->isRunning());
    
    // 模拟接收市场数据
    mockSource->simulateMarketData(testData);
    
    // 等待数据处理
    std::this_thread::sleep_for(milliseconds(100));
    
    // 验证数据接收
    EXPECT_TRUE(dataReceived);
    EXPECT_EQ(receivedSymbol, testData.symbol);
    EXPECT_DOUBLE_EQ(receivedPrice, testData.lastPrice);
    
    // 停止管理器
    manager->stop();
    EXPECT_FALSE(manager->isRunning());
}

TEST_F(MarketDataManagerTest, ErrorHandling) {
    bool errorReceived = false;
    std::string errorMessage;
    
    // 设置错误回调
    manager->setErrorCallback([&](const std::string& error) {
        errorReceived = true;
        errorMessage = error;
    });
    
    // 连接
    EXPECT_TRUE(manager->connect());
    
    // 模拟错误
    mockSource->simulateError("Test error message");
    
    // 验证错误处理
    EXPECT_TRUE(errorReceived);
    EXPECT_EQ(errorMessage, "Test error message");
}

TEST_F(MarketDataManagerTest, MonitorStatus) {
    bool statusChanged = false;
    bool monitorStatus = false;
    
    // 设置监控状态回调
    manager->setMonitorStatusCallback([&](bool status) {
        statusChanged = true;
        monitorStatus = status;
    });
    
    // 连接并订阅
    EXPECT_TRUE(manager->connect());
    EXPECT_TRUE(manager->subscribe({testData.symbol}));
    
    // 启动管理器
    EXPECT_TRUE(manager->start());
    
    // 模拟接收延迟的市场数据（使用过去的时间戳）
    MarketData delayedData = testData;
    delayedData.timestamp = system_clock::now() - seconds(10);
    
    // 发送足够多的延迟数据以触发监控器
    for (int i = 0; i < 10; ++i) {
        mockSource->simulateMarketData(delayedData);
    }
    
    // 等待监控器检测
    std::this_thread::sleep_for(milliseconds(200));
    
    // 验证监控状态变化
    EXPECT_TRUE(statusChanged);
    EXPECT_TRUE(monitorStatus);  // 应该报告异常状态
    
    // 停止管理器
    manager->stop();
}

TEST_F(MarketDataManagerTest, StorageConfiguration) {
    // 设置存储配置
    manager->setMaxStorageFileAge(7);  // 7天
    manager->setStorageFlushInterval(seconds(5));
    manager->setMaxStorageQueueSize(10000);
    
    // 连接并订阅
    EXPECT_TRUE(manager->connect());
    EXPECT_TRUE(manager->subscribe({testData.symbol}));
    
    // 启动管理器
    EXPECT_TRUE(manager->start());
    
    // 模拟接收市场数据
    mockSource->simulateMarketData(testData);
    
    // 等待数据处理和存储
    std::this_thread::sleep_for(milliseconds(200));
    
    // 验证存储文件是否创建
    std::string expectedFilePath = testDir + "/" + testData.symbol + ".csv";
    EXPECT_TRUE(std::filesystem::exists(expectedFilePath));
    
    // 停止管理器
    manager->stop();
}

TEST_F(MarketDataManagerTest, Reconnection) {
    int connectCount = 0;
    
    // 设置连接状态回调
    manager->setConnectionStatusCallback([&](bool status) {
        if (status) {
            connectCount++;
        }
    });
    
    // 启用自动重连
    manager->setAutoReconnect(true);
    manager->setReconnectInterval(milliseconds(100));
    manager->setMaxReconnectAttempts(3);
    
    // 连接
    EXPECT_TRUE(manager->connect());
    EXPECT_EQ(connectCount, 1);
    
    // 模拟断开连接
    mockSource->disconnect();
    
    // 等待自动重连
    std::this_thread::sleep_for(milliseconds(500));
    
    // 应该尝试重连
    EXPECT_GT(connectCount, 1);
}